
#include "ringbuf.h"
#include <string.h>

/*============================================================================
 环形缓存空
 ============================================================================*/
uint8_t api_ringbuf_isEmpty(T_ringbuf *p)
{
	return (p->cnt == 0);
}

/*============================================================================
 环形缓存满
 ============================================================================*/
uint8_t api_ringbuf_isFull(T_ringbuf *p)
{
	return (p->cnt == p->size);
}

/*============================================================================
 获取缓存中字节数
 ============================================================================*/
uint16_t api_ringbuf_get_cnt(T_ringbuf *p)
{
	return p->cnt;
}

/*============================================================================
 写字节
 byte：欲写入的字节
 retval：是否写入成功 不成功为缓存满
 ============================================================================*/
uint8_t api_ringbuf_put(T_ringbuf *p,uint8_t byte)
{
	if(api_ringbuf_isFull(p))
	{
		return RB_FALSE;
	}
	else
	{
		p->ptr[p->pW++] = byte;
		p->cnt++;
		p->w_total++;
		if(p->pW >= p->size)
		{
			p->pW = 0;
		}
	}
	
	return RB_TRUE;
}

/*============================================================================
 写指定长度字节
 pSrc：缓存地址
 len：长度
 retval：实际写入长度
 ============================================================================*/
uint16_t api_ringbuf_puts(T_ringbuf *p,uint8_t *pSrc,uint16_t len)
{
	uint16_t res = 0;

	if(len > p->size)
	{
		len = p->size;
	}

	while(res < len)
	{
		if(api_ringbuf_put(p,*pSrc) != RB_FALSE)
		{
			res++;
			pSrc++;
		}
		else
		{
			break;
		}
	}
	
	return res;
}

/*============================================================================
 环形缓存初始化
 ptr：缓存地址
 size：初始化长度
 ============================================================================*/
uint8_t api_ringbuf_init(T_ringbuf *p,uint8_t *ptr,uint16_t size)
{
	if(ptr == 0)
	{
		return RB_FALSE;
	}
	
	p->pW = 0;
	p->pR = 0;
	p->cnt = 0;
	p->w_total = 0;
	p->r_total = 0;
	p->ptr = ptr;
	p->size = size;

	memset(ptr,0,size);

	return RB_TRUE;

}

/*============================================================================
 环形缓存获得字节
 p:环形缓存对象
 pDes:目标地址
 retval:实际读取长度 0为没取到数据
 ============================================================================*/
uint16_t api_ringbuf_getChar(T_ringbuf *p,uint8_t *pDes)
{
	uint16_t res = 0;

	if(api_ringbuf_isEmpty(p) != RB_TRUE)
	{
		*pDes = p->ptr[p->pR++];
		p->cnt--;
		res++;
		p->r_total++;
		if(p->pR >= p->size)
		{
			p->pR = 0;
		}
	}

	return res;
}

/*============================================================================
 读指定长度字节到目标缓存
 pDes：目标地址
 len：读取长度
 retval：实际读取长度 0为没取到数据
 ============================================================================*/
uint16_t api_ringbuf_gets(T_ringbuf *p,uint8_t *pDes,uint16_t len)
{
	uint16_t res = 0;

	if(len > p->cnt)
	{
		len = p->cnt;
	}

	while(api_ringbuf_getChar(p,pDes) != RB_FALSE)
	{
		res++;
		pDes++;
	}

	return res;
}